use oracle::pool::Pool;

use crate::OracleUserPrelude;

// 查询登录用户权限
pub async fn query_grants(
    pool: &Pool,
    user: &str,
    from_oracle_user_prelude: &OracleUserPrelude,
) -> OracleUserPrelude {
    let mut oracle_user_prelude = OracleUserPrelude::default();

    let sql = format!("SELECT PRIVILEGE from dba_sys_privs WHERE GRANTEE = '{user}'");
    let conn = pool.get().unwrap();
    let rows = conn.query_as::<String>(&sql, &[]).unwrap();
    for row_result in rows {
        let sys_privs = match row_result {
            Ok(row_result) => row_result,
            Err(e) => {
                println!("ERR: {e}");
                continue;
            }
        };
        oracle_user_prelude.sys_privs.push(sys_privs);
    }

    let sql = format!("SELECT GRANTED_ROLE FROM dba_role_privs WHERE GRANTEE = '{user}'");
    let conn = pool.get().unwrap();
    let rows = conn.query_as::<String>(&sql, &[]).unwrap();
    for row_result in rows {
        let role_privs = match row_result {
            Ok(row_result) => row_result,
            Err(e) => {
                println!("ERR: {e}");
                continue;
            }
        };
        oracle_user_prelude.role_privs.push(role_privs);
    }

    let sql = format!("SELECT OWNER, TABLE_NAME, PRIVILEGE FROM dba_tab_privs WHERE GRANTEE = '{user}'");
    let conn = pool.get().unwrap();
    let rows = conn.query_as::<(String, String, String)>(&sql, &[]).unwrap();
    for row_result in rows {
        let tab_privs = match row_result {
            Ok(row_result) => row_result,
            Err(e) => {
                println!("ERR: {e}");
                continue;
            }
        };
        oracle_user_prelude
            .tab_privs
            .entry(format!("{}.{}", tab_privs.0, tab_privs.1))
            .or_insert_with(Vec::new)
            .push(tab_privs.2);
    }

    let mut cond = String::new();
    for (owner, views) in from_oracle_user_prelude.dept_views.clone() {
        if cond.len() > 0 {
            cond = format!("{} OWNER = '{}' OR ", cond, owner);
        } else {
            cond = format!("OWNER = '{}'", owner);
        }
        if views.len() > 0 {
            cond = format!(" ({} and VIEW_NAME in ('{}'))", cond, views.join("','"));
        }
    }
    let sql = format!(
        "select OWNER, VIEW_NAME from dba_views where {}",
        cond.trim_end_matches("OR ")
    );
    let conn = pool.get().unwrap();
    let rows = conn.query_as::<(String, String)>(&sql, &[]).unwrap();
    for row_result in rows {
        let views = match row_result {
            Ok(row_result) => row_result,
            Err(e) => {
                println!("ERR: {e}");
                continue;
            }
        };
        oracle_user_prelude
            .dept_views
            .entry(views.0)
            .or_insert_with(Vec::new)
            .push(views.1);
    }

    oracle_user_prelude
}
